from ctypes import *
import sys

if sys.version_info[0] != 2:
    print('Please, incompatible version of the python. Use >= 2.X')
    exit(0)

from optparse import OptionParser

class CmdOptions:
    This = None
    
    def __init__(self, host):
        self.op = OptionParser()
        self.op.add_option('-t',    '--host',   help='Specifies hostname of target machine;', default=host, dest='host', metavar='HOST')
        self.op.add_option('-w',    '--epweb',  help='Specifies TCP endpoint of WebRPC service, default value: 4592;', default='4592', dest='epweb', metavar='PORT')
        self.op.add_option('-d',    '--epdc',   help='Specifies TCP endpoint of Datacore service, default value: 14592;', default='14592', dest='epdc', metavar='PORT')

    @staticmethod
    def this():
        if CmdOptions.This is None:
            CmdOptions.This = CmdOptions(host ='192.168.86.216')
        return CmdOptions.This

    @staticmethod
    def add_option(*args, **kwargs):
        CmdOptions.this().op.add_option(*args, **kwargs)
        
    @staticmethod
    def parse():
        return CmdOptions.this().op.parse_args()

    @staticmethod
    def help():
        return CmdOptions.this().op.print_help()

    # eoc @CmdOptions

    
c_void = None

RpcWebClientConnect     = windll.bwconn.RpcWebClientConnect
RpcWebClientDisconnect  = windll.bwconn.RpcWebClientDisconnect
RpcWebClientIoctl       = windll.bwconn.RpcWebClientIoctl
RpcDcClientConnect      = windll.bwconn.RpcDcClientConnect
RpcDcClientDisconnect   = windll.bwconn.RpcDcClientDisconnect
RpcDcClientIoctl        = windll.bwconn.RpcDcClientIoctl

# ####################################################################
#   BOOL
#   _stdcall
#   RpcWebClientConnect(
#       __in_opt LPCSTR serviceAddress,
#       __in_opt LPCSTR serviceEndpoint,
#       __in BOOL       fIsDrawMode
#       )
RpcWebClientConnect.restype = c_int
RpcWebClientConnect.argtypes = [c_char_p, c_char_p, c_int]


# ####################################################################
#   VOID
#   _stdcall
#   RpcWebClientDisconnect(
#       VOID
#       )

RpcWebClientDisconnect.restype = c_void
RpcWebClientDisconnect.argtypes = []

# ####################################################################
#   BOOL
#   _stdcall
#   RpcWebClientIoctl(
#       __in DWORD ioctl,
#       __in DWORD sizeIn,
#       __in BYTE *bufferIn,
#       __in DWORD sizeOut,
#       __out BYTE *bufferOut
#       )
RpcWebClientIoctl.restype = c_int
RpcWebClientIoctl.argtypes = [c_uint, c_uint, POINTER(c_ubyte), c_uint, POINTER(c_ubyte)]


# ####################################################################
#   BOOL
#   _stdcall
#   RpcDcClientConnect(
#       __in_opt LPCSTR serviceAddress,
#       __in_opt LPCSTR webServiceEndpoint,
#       __in_opt LPCSTR dcServiceEndpoint
#       )
RpcDcClientConnect.restype = c_int
RpcDcClientConnect.argtypes = [c_char_p, c_char_p, c_char_p]


# ####################################################################
#   VOID
#   _stdcall
#   RpcDcClientDisconnect(
#       VOID
#       )
RpcDcClientDisconnect.restype = c_void
RpcDcClientDisconnect.argtypes = []


# ####################################################################
#   BOOL
#   _stdcall
#   RpcDcClientIoctl(
#       __in DWORD ioctl,
#       __in DWORD sizeIn,
#       __in BYTE *bufferIn,
#       __in DWORD sizeOut,
#       __out BYTE *bufferOut
#       )
RpcDcClientIoctl.restype = c_int
RpcDcClientIoctl.argtypes = [c_uint, c_uint, POINTER(c_ubyte), c_uint, POINTER(c_ubyte)]


class WebIoctl:
    
    # viewsrv.dll:: VsDaqWebService
    eIoctl_case_015845F2    = (0x2710 + 16) # malloc(*bufferIn)
    eIoctl_case_01584656    = (0x2710 + 17) # free(*bufferIn)
    eIoctl_case_015846AD    = (0x2710 + 19) # memcpy(*(bufferIn+4), bufferIn+8, *(bufferIn))
    eIoctl_case_0158472B    = (0x2710 + 31)
    eIoctl_case_0158479C    = (0x2710 + 33)
    eIoctl_case_01584B2D    = (0x2710 + 121)
    eIoctl_case_01584BBF    = (0x2710 + 127)
    eIoctl_case_01584C08    = (0x2710 + 130)
    eIoctl_case_01584C47    = (0x2710 + 132)
    eIoctl_case_01584C65    = (0x2710 + 133)
    eIoctl_case_01584CE8    = (0x2710 + 136)
    eIoctl_case_01584F74    = (0x2710 + 151)
    eIoctl_case_01584FFB    = (0x2710 + 154)
    eIoctl_case_015850D6    = (0x2710 + 160)
    eIoctl_case_015850F5    = (0x2710 + 161)
    eIoctl_case_0158511B    = (0x2710 + 162)
    eIoctl_case_01585137    = (0x2710 + 163)

    # drawsrv.dll ::DsDaqWebService
    eIoctl_case_1000282D    = (0x2710 + 0x7E + 0)
    eIoctl_case_10002848    = (0x2710 + 0x7E + 2)
    eIoctl_case_10002E88    = (0x2710 + 0x7E + 124)
    eIoctl_case_10002EB3    = (0x2710 + 0x7E + 125)
    eIoctl_case_10002F0D    = (0x2710 + 0x7E + 175)

    # BwOpcSvc.dll:: BwSvcFunction
    eIoctl_case_1000112B    = (0xEA60 + 0x4E20 + 1 + 0)
    eIoctl_case_100015D6    = (0xEA60 + 0x4E20 + 1 + 10)
    eIoctl_case_100016A4    = (0xEA60 + 0x4E20 + 1 + 11)
    eIoctl_case_10001792    = (0xEA60 + 0x4E20 + 1 + 20)
    eIoctl_case_10001846    = (0xEA60 + 0x4E20 + 1 + 30)
    eIoctl_case_1000196C    = (0xEA60 + 0x4E20 + 1 + 51)

    # BwWebSvc.dll:: BwSvcFunction
    eIoctl_case_10004640    = (0xEA60 + 0x5208 + 1 + 4)
    eIoctl_case_10004670    = (0xEA60 + 0x5208 + 1 + 8)
    eIoctl_case_100046EF    = (0xEA60 + 0x5208 + 1 + 11)
    eIoctl_case_1000473F    = (0xEA60 + 0x5208 + 1 + 12)
    eIoctl_case_10004792    = (0xEA60 + 0x5208 + 1 + 13)
    eIoctl_case_100049EE    = (0xEA60 + 0x5208 + 1 + 16)
    eIoctl_case_100049BE    = (0xEA60 + 0x5208 + 1 + 18)
    eIoctl_case_1000498E    = (0xEA60 + 0x5208 + 1 + 19)
    eIoctl_case_100047EF    = (0xEA60 + 0x5208 + 1 + 20)
    eIoctl_case_10004891    = (0xEA60 + 0x5208 + 1 + 21)
    eIoctl_case_100048F5    = (0xEA60 + 0x5208 + 1 + 22)
    eIoctl_case_10004959    = (0xEA60 + 0x5208 + 1 + 23)
    eIoctl_case_10004835    = (0xEA60 + 0x5208 + 1 + 26)

    # BwPAlarm.dll:: BwRPCPAlarmService
    eIoctl_case_07002193    = (0xEA60 + 0x2711 + 1)     # BwRpcP_PutNode
    #eIoctl_case_07001AB2    = (0xEA60 + 0x2711 + 2)
    eIoctl_case_07002321    = (0xEA60 + 0x2711 + 2)
    eIoctl_case_07002B62    = (0xEA60 + 0x2711 + 6)
    eIoctl_case_07002BDA    = (0xEA60 + 0x2711 + 7)
    eIoctl_case_07002CE7    = (0xEA60 + 0x2711 + 10)
    eIoctl_case_070027A2    = (0xEA60 + 0x2711 + 19)
    
    eIoctl_case_070033A0    = (0xEA60 + 0x2906)
    eIoctl_case_07003412    = (0xEA60 + 0x2907)         # BwRpcP_GetValueText
    eIoctl_case_070034D5    = (0xEA60 + 0x2908)         # BwRpcP_SetValueText
        
    eIoctl_case_070034B1    = (0xEA60 + 0x2908 + 1)
    eIoctl_case_0700346F    = (0xEA60 + 0x2908 + 2)

    eIoctl_case_07003516    = (0xEA60 + 0x2910)         # BwRpcP_ServerSetValueText

    # for vuln.047-vuln.051
    eIoctl_case_070035C8    = (0xEA60 + 0x2913 + 18)    # BwRpcP_KernelShutdown
    
    eIoctl_Max              = 0x7FFFFFFF


class DcIoctl:
    eIoctl_case_1002D4CF    = (0x7530 + 0x3e8 + 1 + 5)
    eIoctl_case_1002D8E8    = (0x7530 + 0x3e8 + 1 + 7)

    eIoCtl_case_1002AD6D    = (0x4e20 + 0x3e8 + 0)
    eIoctl_case_1002B753    = (0x4e20 + 0x3e8 + 16)
    eIoctl_case_1002B76D    = (0x4e20 + 0x3e8 + 17)
    eIoctl_case_1002BCE8    = (0x4e20 + 0x3e8 + 21)
    eIoctl_case_1002B935    = (0x4e20 + 0x3e8 + 30)     # dc_get_userpass_by_username
    eIoctl_case_1002BF37    = (0x4e20 + 0x3e8 + 31)
    eIoctl_case_1002C001    = (0x4e20 + 0x3e8 + 32)
    eIoctl_case_1002B839    = (0x4e20 + 0x3e8 + 50)
    eIoctl_case_1002B8CF    = (0x4e20 + 0x3e8 + 51)
    eIoctl_case_1002B902    = (0x4e20 + 0x3e8 + 52)
    eIoctl_case_1002B571    = (0x4e20 + 0x3e8 + 53)
    eIoctl_case_1002C1C5    = (0x4e20 + 0x3e8 + 54)
    
    eIoctl_Max              = 0x7FFFFFFF
    pass
